import fecha from 'fecha'
import { detect } from 'detect-browser'

/**
 * Utility function to generate table column object used by table components's columns prop
 * @param {String} name Column name
 * @param {String} title Column title
 * @param {Boolean} sortable Indicates whether the column is sortable
 * @param {String} hidden Indicates whether to hide the column
 */
export const createTableColumn = (
  name,
  title,
  sortable = false,
  hidden = false
) => {
  return {
    name,
    title,
    sortable: sortable ? 'custom' : false,
    hidden
  }
}

export const date = {
  format: (value, format = 'YYYY-MM-DD') => {
    if (!value) return value
    return fecha.format(value, format)
  },
  parse: fecha.parse
}

/**
 * Utility method to generate cumtomized validator used by form validation.
 * @param {*} rules Array of rule object which has `expression` and message `field`.
 */
export const createValidator = (rules = []) => {
  return (rule, value, callback) => {
    rules.forEach(rule => {
      if (!rule.expression.test(value)) {
        return callback(rule.message)
      }
    })
    callback()
  }
}

/**
 * Utility method to generate a validation rule object
 */
export const createValidationRule = (
  message,
  type = 'string',
  required = true,
  trigger = 'blur'
) => {
  return {
    message,
    type,
    required,
    trigger
  }
}

/**
 * Utility method to generate option object used by `select`, `checkbox` or `radio` input.
 * @param {*} value Value field
 * @param {String} label Label field
 */
export const createOption = (value, label) => {
  return {
    value,
    label: label || value
  }
}

/**
 * 初始化七牛文件上传组件
 * @param {String} containerId 上传组建容器DOM的ID
 * @param {String} browseButtonId 上传组建文件选择按钮DOM的ID
 * @param {String} uploadToken 上传凭证
 * @param {String} domain bucket域名
 * @param {Function} uploadedCallback 上传成功后的回调函数
 */
export const initUploader = (
  containerId,
  browseButtonId,
  uploadToken,
  domain,
  uploadedCallback
) => {
  window.Qiniu.uploader({
    runtimes: 'html5,flash,html4', // 上传模式，依次退化
    browse_button: browseButtonId, // 上传选择的点选按钮，必需
    // 在初始化时，uptoken，uptoken_url，uptoken_func三个参数中必须有一个被设置
    // 切如果提供了多个，其优先级为uptoken > uptoken_url > uptoken_func
    // 其中uptoken是直接提供上传凭证，uptoken_url是提供了获取上传凭证的地址，如果需要定制获取uptoken的过程则可以设置uptoken_func
    uptoken: uploadToken, // uptoken是上传凭证，由其他程序生成
    // uptoken_url: 'http://172.25.128.1:17563/ebianque/service/qiniu/upload-token',         // Ajax请求uptoken的Url，强烈建议设置（服务端提供）
    // uptoken_func: function(){    // 在需要获取uptoken时，该方法会被调用
    //    // do something
    //    return uptoken;
    // },
    get_new_uptoken: false, // 设置上传文件的时候是否每次都重新获取新的uptoken
    // downtoken_url: '/downtoken',
    // Ajax请求downToken的Url，私有空间时使用，JS-SDK将向该地址POST文件的key和domain，服务端返回的JSON必须包含url字段，url值为该文件的下载地址
    unique_names: true, // 默认false，key为文件名。若开启该选项，JS-SDK会为每个文件自动生成key（文件名）
    // save_key: true,                  // 默认false。若在服务端生成uptoken的上传策略中指定了sava_key，则开启，SDK在前端将不对key进行任何处理
    domain: domain, // bucket域名，下载资源时用到，必需
    container: containerId, // 上传区域DOM ID，默认是browser_button的父元素
    max_file_size: '2mb', // 最大文件体积限制
    // flash_swf_url: 'path/of/plupload/Moxie.swf',  //引入flash，相对路径
    max_retries: 3, // 上传失败最大重试次数
    dragdrop: true, // 开启可拖曳上传
    drop_element: containerId, // 拖曳上传区域元素的ID，拖曳文件或文件夹后可触发上传
    chunk_size: '2mb', // 分块上传时，每块的体积
    auto_start: true, // 选择文件后自动上传，若关闭需要自己绑定事件触发上传
    // x_vars : {
    //    查看自定义变量
    //    'time' : function(up,file) {
    //        var time = (new Date()).getTime();
    // do something with 'time'
    //        return time;
    //    },
    //    'size' : function(up,file) {
    //        var size = file.size;
    // do something with 'size'
    //        return size;
    //    }
    // },
    init: {
      FilesAdded: function(up, files) {
        window.plupload.each(files, function(file) {
          // 文件添加进队列后，处理相关的事情
        })
      },
      BeforeUpload: function(up, file) {
        // 每个文件上传前，处理相关的事情
      },
      UploadProgress: function(up, file) {
        // 每个文件上传时，处理相关的事情
      },
      FileUploaded: function(up, file, info) {
        uploadedCallback && uploadedCallback(up, file, info)
        // 每个文件上传成功后，处理相关的事情
        // 其中info是文件上传成功后，服务端返回的json，形式如：
        // {
        //    "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",
        //    "key": "gogopher.jpg"
        //  }
        // 查看简单反馈
        // var domain = up.getOption('domain');
        // var res = parseJSON(info);
        // var sourceLink = domain +"/"+ res.key; 获取上传成功后的文件的Url
      },
      Error: function(up, err, errTip) {
        // 上传出错时，处理相关的事情
      },
      UploadComplete: function() {
        // 队列文件处理完毕后，处理相关的事情
      },
      Key: function(up, file) {
        // 若想在前端对每个文件的key进行个性化处理，可以配置该函数
        // 该配置必须要在unique_names: false，save_key: false时才生效

        var key = ''
        // do something with key here
        return key
      }
    }
  })
  // domain为七牛空间对应的域名，选择某个空间后，可通过 空间设置->基本设置->域名设置 查看获取
  // uploader为一个plupload对象，继承了所有plupload的方法
}

/**
 * Utility function to parse dictionary object to option object
 * @param {Object} dictionary Object which has `code` and `label` field
 * @return {Object} Object which has `value` and `label` field
 */
export const parseDictionaryToOption = dictionary => {
  return {
    value: dictionary.code,
    label: dictionary.label
  }
}

/**
 * Get file extension by its filename
 * @param {String} fileName Name of the fine
 */
export const getFileExtension = fileName => {
  if (!fileName) return ''
  return fileName.split('.').pop()
}

export const either = (objValue, srcValue) => {
  return objValue || srcValue
}

const traverse = (obj, fn) => {
  if (
    !obj ||
    !(typeof obj === 'object') ||
    !fn ||
    !(typeof fn === 'function')
  ) {
    return
  }

  for (let key of Object.keys(obj)) {
    fn(obj, key)
    traverse(obj[key], fn)
  }
}

export const resetDeep = (obj, defaultValue = undefined) => {
  console.log(`before resetDeep: ${JSON.stringify(obj)}`)
  traverse(obj, (obj, key) => {
    obj[key] = obj[key] || defaultValue
  })
  return obj
}

export const browserCampatible = () => {
  const browser = detect()

  // handle the case where we don't detect the browser
  if (browser) {
    const name = browser.name
    const version = browser.version
    console.log(`browser name: ${name}`)
    console.log(`browser version: ${version}`)

    return name !== 'ie' || version.indexOf('11.') === 0 // 仅支持非IE浏览器和IE11
  }

  return false
}

export const addDefaultOption = (options, label) => {
  return options.unshift({ label, value: '' })
}

/**
 * 将对象中值为''或null的属性删除，该操作为递归操作
 */
export const clearDeep = obj => {
  if (!obj || !typeof obj === 'object') return

  const keys = Object.keys(obj)
  for (var key of keys) {
    const val = obj[key]
    if (
      typeof val === 'undefined' ||
      ((typeof val === 'object' || typeof val === 'string') && !val)
    ) {
      // 如属性值为null或undefined或''，则将该属性删除
      delete obj[key]
    } else if (typeof val === 'object') {
      // 属性值为对象，递归调用
      clearDeep(obj[key])

      // if (Object.keys(obj[key]).length === 0) {
      //   // 如某属性的值为不包含任何属性的独享，则将该属性删除
      //   delete obj[key]
      // }
    }
  }
}

export const getUUID = () => {
  var s = []
  var hexDigits = '0123456789abcdef'
  for (var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
  }
  s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = '-'

  var uuid = s.join('')
  return uuid
}
